﻿using System;
using Object = UnityEngine.Object;

namespace Framework
{
    public class ResLoader : IDisposable
    {
        public event Action<ResLoader> Completed;
        public Resource resource { get; private set; }
        public bool isLoading { get; private set; }
        
        public ResLoader(Resource resource)
        {
            this.resource = resource;
            this.resource.Retain();
            isLoading = false;
        }

        public virtual void Dispose()
        {
            resource.Release();
            resource = null;
            Completed = null;
        }
        
        public void Start()
        {
            isLoading = true;
            OnStart();
        }

        public void Cancel()
        {
            isLoading = false;
            OnCancel();
        }

        public virtual void GetProgress(out int current, out int total)
        {
            throw new Exception("To implement this method");
        }

        protected virtual void OnStart()
        {
            throw new Exception("To implement this method");
        }

        protected virtual void OnCancel()
        {
            throw new Exception("To implement this method");
        }
        
        protected void OnSuccess(Object asset)
        {
            if (resource != null)
            {
                resource.SetAsset(asset);
                OnCompleted();                
            }
        }

        protected void OnSuccess(byte[] bytes)
        {
            if (resource != null)
            {            
                resource.SetBytes(bytes);
                OnCompleted();
            }
        }

        protected void OnSuccess(string text)
        {
            if (resource != null)
            {            
                resource.SetText(text);
                OnCompleted();
            }
        }
        
        protected void OnFail(string error)
        {
            if (resource != null)
            {            
                resource.SetError(error);
                OnCompleted();
            }
        }

        private void OnCompleted()
        {
            isLoading = false;
            if (Completed != null)
            {
                Completed.Invoke(this);
            }
        }
    }
}